package com.saret.crawler.search;


import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.saret.crawler.type.GUrl;
import com.saret.crawler.type.GUrlImpl;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.HttpURL;
import org.apache.commons.httpclient.methods.GetMethod;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * User: biniam.gebremichael
 * Date: 2/10/11
 */
public class YahooWebSearch implements WebSearch {

    static int total = 1000;
    static int max = 50;
    static String request = "http://api.search.yahoo.com/WebSearchService/V1/webSearch?appid={KEY}&query={QUERY}&output=json&start={START}&results=" + max;
    final String key;

    @Inject
    public YahooWebSearch(@Named("saret.yahoo.searchKeys") String key) {
        this.key = key;
    }

    public List<GUrl> search(String searchKey) {
        List<GUrl> result = new ArrayList<GUrl>();
        boolean stop = false;


        int index = 0;
        try {
            do {
                JSONObject jo = new JSONObject(internalSearch(this.key, searchKey, index)).getJSONObject("ResultSet");
                JSONArray ja = jo.getJSONArray("Result");

                int resultCount = ja.length();
                index = index + resultCount;
                if (resultCount < max || index > total) {
                    stop = true;
                }
                for (int i = 0; i < resultCount; i++) {
                    JSONObject resultObject = ja.getJSONObject(i);
                    result.add(
                            new GUrlImpl(
                                    resultObject.getString("Url"), 0,
                                    resultObject.getString("Summary"),
                                    resultObject.getString("MimeType") ,null,null
                            ));
                }

                System.err.print(resultCount + ".");
            } while (!stop);

        } catch (Exception e) {
            System.err.println(e.getMessage() + " Error seaching: " + searchKey);
        }

        return result;
    }


    public static InputStream getStream(String key, String searchKey, int index) throws Exception {

        String query = request.replace("{QUERY}", searchKey).replace("{KEY}", key).replace("{START}", String.valueOf(index));
        System.err.print(query);
        HttpClient client = new HttpClient();
        GetMethod method = new GetMethod(new HttpURL(query).getEscapedURI());
        int statusCode = client.executeMethod(method);

        if (statusCode != HttpStatus.SC_OK) {
            System.err.println(" Method failed due to " + method.getStatusLine());
        }

        return method.getResponseBodyAsStream();
    }

    public static String internalSearch(String key, String args, int index) throws Exception {

        BufferedReader br = new BufferedReader(new InputStreamReader(getStream(key, args, index)));
        String jsonString = "";
        String line;
        while ((line = br.readLine()) != null) {
            jsonString += line;
        }
        br.close();

        return jsonString;
    }
}
